<template>
  <div class="parent-container">
    <!-- 左侧步骤条 -->
    <div class="steps-container">
      <div
          v-for="(step, index) in steps"
          :key="index"
          :class="['step-item', { 'active': currentStep === index }]"
          @click="scrollToComponent(index)"
      >
        {{ step.title }}
      </div>
    </div>

    <!-- 右侧内容区域 -->
    <div ref="contentContainer" class="content-container" @scroll="handleScroll">
      <div
          v-for="(component, index) in components"
          :key="index"
          :ref="(el) => setComponentRef(el, index)"
          class="component-section"
      >
        <component :is="component"/>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import {ref, onMounted, onBeforeUnmount} from 'vue'
import A from './A.vue'
import B from './B.vue'
import C from './C.vue'
import D from './D.vue'
import E from './E.vue'

// 定义步骤数据
const steps = [
  {title: '步骤 A', component: A},
  {title: '步骤 B', component: B},
  {title: '步骤 C', component: C},
  {title: '步骤 D', component: D},
  {title: '步骤 E', component: E}
]

const components = steps.map(step => step.component)
const contentContainer = ref<HTMLElement | null>(null)
const componentRefs = ref<HTMLElement[]>([])
const currentStep = ref(0)
let observer: IntersectionObserver | null = null

// 设置组件ref
const setComponentRef = (el: any, index: number) => {
  if (el) {
    componentRefs.value[index] = el
  }
}

// 滚动到指定组件
const scrollToComponent = (index: number) => {
  if (componentRefs.value[index] && contentContainer.value) {
    currentStep.value = index
    componentRefs.value[index].scrollIntoView({behavior: 'smooth'})
  }
}

// 处理滚动事件
const handleScroll = () => {
  if (!contentContainer.value || componentRefs.value.length === 0) return

  const container = contentContainer.value
  const containerRect = container.getBoundingClientRect()

  componentRefs.value.forEach((comp: HTMLElement, index: number) => {
    const compRect = comp.getBoundingClientRect()
    const compTopRelativeToContainer = compRect.top - containerRect.top

    // 更精确的可见性检测
    const isComponentVisible = (
        compTopRelativeToContainer >= 0 &&
        compTopRelativeToContainer <= container.clientHeight / 2
    )

    if (isComponentVisible) {
      currentStep.value = index
    }
  })
}

// 使用IntersectionObserver监听元素可见性
const setupIntersectionObserver = () => {
  if (!contentContainer.value) return

  observer = new IntersectionObserver(
      (entries) => {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            const index = componentRefs.value.findIndex(comp => comp === entry.target)
            if (index !== -1) {
              currentStep.value = index
            }
          }
        })
      },
      {
        root: contentContainer.value,
        threshold: 0.5
      }
  )

  componentRefs.value.forEach(comp => {
    if (comp) observer?.observe(comp)
  })
}

onMounted(() => {
  setupIntersectionObserver()
})

onBeforeUnmount(() => {
  observer?.disconnect()
})
</script>

<style scoped>
.parent-container {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

.steps-container {
  width: 200px;
  background-color: #f5f5f5;
  padding: 20px;
  overflow-y: auto;
  border-right: 1px solid #e0e0e0;
}

.step-item {
  padding: 10px;
  margin-bottom: 10px;
  cursor: pointer;
  border-radius: 4px;
  transition: all 0.3s;
}

.step-item:hover {
  background-color: #e0e0e0;
}

.step-item.active {
  background-color: #1890ff;
  color: white;
}

.content-container {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
}

.component-section {
  min-height: 100vh;
  padding: 20px;
  margin-bottom: 20px;
  border-bottom: 1px solid #e0e0e0;
}
</style>